package com.sdu.rpc.server;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;

public class ServiceCache {

	private static Map<String, Object> serviceCache = new ConcurrentHashMap<>();

	private static Map<String, Method> methodCache = new ConcurrentHashMap<>();

	public static void registerService(String interfaceName, Object serviceImpl) {
		serviceCache.put(interfaceName, serviceImpl);
	}

	public static Object getServiceImpl(String className) {
		return serviceCache.get(className);
	}

	public static Method getMethod(String className, String methodName, Object[] parameters) {
		try {
			String fullName = className + "." + methodName;
			String parametersName = "";
			if (parameters != null) {
				StringJoiner joiner = new StringJoiner(".");
				for (int i = 0; i < parameters.length; i++) {
					joiner.add(parameters[i].getClass().getName());
				}
				parametersName = joiner.toString();
			}
			if (parametersName.length() > 0) {
				fullName = fullName + "." + parametersName;
			}

			Method method = methodCache.get(fullName);
			Object service = serviceCache.get(className);
			if (method == null) {
				if (parameters != null) {
					method = service.getClass().getDeclaredMethod(methodName, getParameterTypes(parameters));
				} else {
					method = service.getClass().getDeclaredMethod(methodName);
				}

				methodCache.put(fullName, method);
			}
			return method;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}

		return null;

	}

	private static Class<?>[] getParameterTypes(Object[] parameters) {
		Class<?>[] parameterTypes = new Class<?>[parameters.length];
		for (int i = 0; i < parameters.length; i++) {
			parameterTypes[i] = parameters[i].getClass();
		}
		return parameterTypes;
	}

}
